package cn.wolfcode.wolf2w.business.service.impl;

import cn.wolfcode.wolf2w.business.api.*;
import cn.wolfcode.wolf2w.business.api.domain.*;
import cn.wolfcode.wolf2w.business.query.SearchQuery;
import cn.wolfcode.wolf2w.business.repository.DestinationEsRepository;
import cn.wolfcode.wolf2w.business.repository.NoteEsRepository;
import cn.wolfcode.wolf2w.business.repository.StrategyEsRepository;
import cn.wolfcode.wolf2w.business.repository.UserinfoEsRepository;
import cn.wolfcode.wolf2w.business.service.ISearchService;
import cn.wolfcode.wolf2w.common.core.constant.SecurityConstants;
import cn.wolfcode.wolf2w.member.api.RemoteUserInfoService;
import cn.wolfcode.wolf2w.member.api.domain.UserInfo;
import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ISearchServiceImpl implements ISearchService {
    @Autowired
    private StrategyEsRepository repository;

    //用于查询高亮等复杂查询
    @Autowired
    private ElasticsearchRestTemplate template;

    @Autowired
    private RemoteStrategyService remoteStrategyService;

    @Autowired
    private UserinfoEsRepository userinfoEsRepository;

    @Autowired
    private RemoteUserInfoService remoteUserInfoService;

    @Autowired
    private NoteEsRepository noteEsRepository;
    @Autowired
    private RemoteNoteService remoteNoteService;

    @Autowired
    private DestinationEsRepository destinationEsRepository;
    @Autowired
    private RemoteDestinationService remoteDestinationService;

    @Override
    public void saveStrategy(StrategyEs strategyEs) {
        repository.save(strategyEs);
    }

    @Override
    public void saveUserInfo(UserinfoEs userinfoEs) {
        userinfoEsRepository.save(userinfoEs);
    }

    @Override
    public void saveNote(NoteEs noteEs) {
        noteEsRepository.save(noteEs);
    }

    @Override
    public void saveDestination(DestinationEs destinationEs) {
        destinationEsRepository.save(destinationEs);
    }

    @Override
    public <T> Page<T> searchWithHighLight(Class<T> clazz, Class<?> esClazz, SearchQuery qo, String... fields) throws InvocationTargetException, IllegalAccessException {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withQuery(
                //使用多列查询第一个参数：搜索的内容，第二个参数：搜索的列
                QueryBuilders.multiMatchQuery(qo.getKeyword(),fields)
        );
        //设置分页条件 参数1：当前页数，参数2：每页显示的记录数
        Pageable pageable= PageRequest.of(qo.getCurrentPage()-1, qo.getPageSize());
        builder.withPageable(pageable);

        //设置高亮条件
        List<HighlightBuilder.Field> fs=new ArrayList<>();
        for (String name : fields) {
            HighlightBuilder.Field field=new HighlightBuilder.Field(name);
            field.preTags("<span style='color:red'>").postTags("</span>");
            fs.add(field);
        }
        builder.withHighlightFields(fs);
        //执行查询
        List<T> list=new ArrayList<>();
        SearchHits<?> hits = template.search(builder.build(), esClazz);
        long totalCount = hits.getTotalHits();
        for (SearchHit<?> searchHit : hits.getSearchHits()) {
            Long id = Long.valueOf(searchHit.getId());
            T t=null;//用于存储mysql中的对象
            if (clazz== Strategy.class){
                t=(T)remoteStrategyService.getOne(id, SecurityConstants.INNER).getData();
            }else if (clazz== UserInfo.class){
                t= (T) remoteUserInfoService.getOne(id, SecurityConstants.INNER).getData();
            }else if (clazz== Note.class){
                t= (T) remoteNoteService.getOne(id, SecurityConstants.INNER).getData();
            }else if (clazz== Destination.class){
                t= (T) remoteDestinationService.getOne(id, SecurityConstants.INNER).getData();
            }
            list.add(t);
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            for (String key : highlightFields.keySet()) {
                List<String> arr = highlightFields.get(key);
                StringBuffer stringBuffer = new StringBuffer();
                for (String s : arr) {
                    stringBuffer.append(s).append(" ");
                }
                String value=stringBuffer.toString();
                //设置t对象的key属性为value值
                BeanUtils.setProperty(t,key,value);
            }
        }
        //构建分页对象 参数1：当前页数据，参数2：分页条件，参数3：总记录数
        //一个分页对象的数据当前页、每页条数、总页数、总条数、当前页数、上一页、下一页
        return new PageImpl<>(list,pageable,totalCount);

    }


}
